import React, { memo, useCallback, useMemo } from 'react';
import type { LayoutChangeEvent } from 'react-native';
import { PanGestureHandler } from 'react-native-gesture-handler';
import Animated from 'react-native-reanimated';
import { useAdaptiveSheetGestureHandlers, useAdaptiveSheetInternal } from '../../hooks';
import { print } from '../../utilities';
import type { AdaptiveSheetHandleContainerProps } from './types';
import AdaptiveSheetHandle from '../adaptiveSheetHandle';

function AdaptiveSheetHandleContainerComponent({
  animatedIndex,
  animatedPosition,
  simultaneousHandlers: _internalSimultaneousHandlers,
  enableHandlePanningGesture,
  handleHeight,
  handleComponent: _providedHandleComponent,
  handleStyle: _providedHandleStyle,
  handleIndicatorStyle: _providedIndicatorStyle,
}: AdaptiveSheetHandleContainerProps): JSX.Element | null {
  const { activeOffsetX, activeOffsetY, failOffsetX, failOffsetY, waitFor, simultaneousHandlers: _providedSimultaneousHandlers } = useAdaptiveSheetInternal();
  const { handlePanGestureHandler } = useAdaptiveSheetGestureHandlers();

  const simultaneousHandlers = useMemo<React.Ref<unknown>[]>(() => {
    const refs: React.Ref<unknown>[] = [];

    if (_internalSimultaneousHandlers) {
      if (Array.isArray(_internalSimultaneousHandlers)) {
        refs.push(..._internalSimultaneousHandlers);
      } else {
        refs.push(_internalSimultaneousHandlers);
      }
    }

    if (_providedSimultaneousHandlers) {
      if (Array.isArray(_providedSimultaneousHandlers)) {
        refs.push(..._providedSimultaneousHandlers);
      } else {
        refs.push(_providedSimultaneousHandlers);
      }
    }

    return refs;
  }, [_providedSimultaneousHandlers, _internalSimultaneousHandlers]);

  const handleContainerLayout = useCallback(
    function handleContainerLayout({
      nativeEvent: {
        layout: { height },
      },
    }: LayoutChangeEvent) {
      handleHeight.value = height;

      print({
        component: AdaptiveSheetHandleContainer.displayName,
        method: 'handleContainerLayout',
        params: {
          height,
        },
      });
    },
    [handleHeight],
  );

  const HandleComponent = _providedHandleComponent === undefined ? AdaptiveSheetHandle : _providedHandleComponent;
  return HandleComponent !== null ? (
    <PanGestureHandler
      enabled={enableHandlePanningGesture}
      waitFor={waitFor}
      simultaneousHandlers={simultaneousHandlers}
      shouldCancelWhenOutside={false}
      activeOffsetX={activeOffsetX}
      activeOffsetY={activeOffsetY}
      failOffsetX={failOffsetX}
      failOffsetY={failOffsetY}
      onGestureEvent={handlePanGestureHandler}>
      <Animated.View key="AdaptiveSheetHandleContainer" onLayout={handleContainerLayout}>
        <HandleComponent
          animatedIndex={animatedIndex}
          animatedPosition={animatedPosition}
          style={_providedHandleStyle}
          indicatorStyle={_providedIndicatorStyle}
        />
      </Animated.View>
    </PanGestureHandler>
  ) : null;
  //#endregion
}

const AdaptiveSheetHandleContainer = memo(AdaptiveSheetHandleContainerComponent);
AdaptiveSheetHandleContainer.displayName = 'AdaptiveSheetHandleContainer';

export default AdaptiveSheetHandleContainer;
